home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / MRDiim, 3D World Shell / MRDiim.sit / MRDiim / MRConstruction.cp < prev    next >
Text File  |  1994-12-19  |  11KB  |  436 lines

  1. #include<QDOffScreen.h>
  2. #include"Utils_General.h"
  3. #include"MRRachet.h"
  4. #include"MREyeBall.h"
  5. #include"MRConstruction.h"
  6. #include"MRDiim.h"
  7. #include <math.h>
  8.  
  9. //wall's pattern for fill
  10. extern PixPatHandle    WallPenPattern[2][3];
  11.  
  12.     MRConstruction::MRConstruction(short Number,Boolean toMark) : MRRachet(Number,toMark)
  13. {
  14.     myBuildType=0;
  15.     myStructure=nil;
  16.     myActors=nil;
  17.     oDistance = 0;
  18.     // clears this everytime a new one is added (static)
  19.     maxDist=0;
  20.     nextDist=0;
  21.     myWallType=0;
  22.  
  23. }
  24.  
  25. // statics
  26. static float MRConstruction::maxDist;
  27. static float MRConstruction::nextDist;
  28.  
  29.     MRConstruction::~MRConstruction(void)
  30. {
  31.     if(GetNum()!=0)
  32.     {
  33.         switch(myBuildType)
  34.         {
  35.             case 1:
  36.             {
  37.                 delete((ChartPost *)myStructure);
  38.                 delete((ChartPost *)myActors);
  39.                 break;
  40.             }
  41.             case 2:
  42.             {
  43.                 delete((ChartWall *)myStructure);
  44.                 delete((ChartWall *)myActors);
  45.                 break;
  46.             }
  47.         }
  48.     }
  49. }
  50.     
  51. void        *MRConstruction::NewRachet(short Number,Boolean toMark)
  52. {
  53.     return(new MRConstruction(Number,toMark));
  54. }
  55.  
  56. void        MRConstruction::ZapRachet(Ptr toBeZapped)
  57. {
  58.     delete (MRConstruction *) toBeZapped;
  59. }
  60.  
  61. void        MRConstruction::AddConstruction(ChartPost theCP, char wallType)
  62. {  //  post
  63.     if(HasNext())
  64.         ((MRConstruction *) NextRachet)->AddConstruction(theCP,wallType);
  65.     else
  66.     {
  67.         // create the next link
  68.         CreateNew(GetMarked());
  69.         // create a ChartPost for the data set
  70.         ((MRConstruction *) NextRachet)->myStructure=new ChartPost;
  71.         // I think that this copies the contents of theCP into the rachet's data structure
  72.         * ((ChartPost *) (((MRConstruction *) NextRachet)->myStructure)) = theCP;
  73.         // create a ChartPost Actors
  74.         ((MRConstruction *) NextRachet)->myActors=new ChartPost;
  75.         // copy data into the actors (not used, just filler)
  76.         * ((ChartPost *) (((MRConstruction *) NextRachet)->myActors)) = ZeroZeroPost;
  77.         // mark the dataset as a post [1]
  78.         ((MRConstruction *) NextRachet)->myBuildType = 1;
  79.         // set the wallType
  80.         ((MRConstruction *) NextRachet)->myWallType = wallType;
  81.         
  82.     }
  83. }
  84.  
  85. void        MRConstruction::AddConstruction(ChartWall theCW, char wallType)
  86. {  //  wall
  87.     if(HasNext())
  88.         ((MRConstruction *) NextRachet)->AddConstruction(theCW,wallType);
  89.     else
  90.     {
  91.         // create the next link
  92.         CreateNew(GetMarked());
  93.         // create a ChartWall for the data set
  94.         ((MRConstruction *) NextRachet)->myStructure=new ChartWall;
  95.         // I think that this copies the contents of theCP into the rachet's data structure
  96.         * ((ChartWall *) (((MRConstruction *) NextRachet)->myStructure)) = theCW;
  97.         // create a ChartWall Actor
  98.         ((MRConstruction *) NextRachet)->myActors=new ChartWall;
  99.         // copy data into the actors (not used, just filler)
  100.         * ((ChartWall *) (((MRConstruction *) NextRachet)->myActors)) = ReturnChartWall(ZeroZeroPost,ZeroZeroPost);
  101.         // mark the dataset as a wall [2]
  102.         ((MRConstruction *) NextRachet)->myBuildType = 2;
  103.         // set the wallType
  104.         ((MRConstruction *) NextRachet)->myWallType = wallType;
  105.         
  106.     }
  107. }
  108.  
  109. void        MRConstruction::FindActors(ChartPost myself,float facing,Boolean halfCircle)
  110. {
  111.     ChartPost    actor1={0,0};
  112.     ChartPost    actor2={0,0};
  113.     
  114.     
  115.     
  116.     if(GetNum()==0)
  117.     {
  118.     maxDist=MaxViewDistance;
  119.     nextDist=0;    
  120.     }
  121.     else
  122.     {
  123.         switch(myBuildType)
  124.         {
  125.             case 1:
  126.             {
  127.                 actor1 = FindActor(DiffChartPost(myself,* ((ChartPost *) myStructure) ),facing,halfCircle);
  128.                 * (ChartPost *) myActors = actor1;
  129.                 oDistance = sqrt(actor1.myX*actor1.myX+actor1.myY*actor1.myY);
  130.                 break;
  131.             }
  132.             case 2:
  133.             {
  134.                 actor1 = FindActor(DiffChartPost(myself,(* ((ChartWall *) myStructure)).CP1),facing,halfCircle);
  135.                 actor2 = FindActor(DiffChartPost(myself,(* ((ChartWall *) myStructure)).CP2),facing,halfCircle);
  136.                 if(((actor1.myY>0)&&(actor2.myY<0))||((actor1.myY<0)&&(actor2.myY>0)))
  137.                 { // crosses y=0, fix it so it's seen
  138.                     // get the slope
  139.                     float slopeMainLine = (actor2.myY-actor1.myY)/( (actor2.myX-actor1.myX)==0 ? .017 : (actor2.myX-actor1.myX) ) ;
  140.                     // we don't want exactly zero
  141.                     if(slopeMainLine==0)
  142.                         slopeMainLine=.017;
  143.                     // get b of the line
  144.                     float    bMainLine = actor1.myY - (slopeMainLine*actor1.myX);
  145.                     // prepare the X intercept in case of a close wall
  146.                     float    theCrossX = -bMainLine/slopeMainLine;
  147.                     if ( (theCrossX<1) &&(theCrossX>=0) )
  148.                         theCrossX = 1;
  149.                     if ( (theCrossX>-1) &&(theCrossX<0) )
  150.                         theCrossX = -1;
  151.                     // replace the point behind line of sight
  152.                     if(actor1.myY>0)
  153.                         actor2=ReturnChartPost(theCrossX,0);
  154.                     else
  155.                         actor1=ReturnChartPost(theCrossX,0);
  156.                 }
  157.                 * (ChartWall *) myActors = ReturnChartWall(actor1,actor2);
  158.                 oDistance = sqrt(pow((actor1.myX+actor2.myX)/2,2)+pow((actor1.myY+actor2.myY)/2,2));
  159.                 break;
  160.             }
  161.         }
  162.     }
  163.     SetMarked((oDistance<MaxViewDistance) && (actor1.myY>=0));
  164.     if(HasNext())
  165.         ((MRConstruction *) NextRachet)->FindActors(myself,facing,halfCircle);
  166. }
  167.  
  168. void        MRConstruction::PrepScanStart(void)
  169. {
  170.     maxDist = MaxViewDistance;
  171.     nextDist = 0;
  172. }
  173.  
  174. void        MRConstruction::PrepScan(void)
  175. {
  176.     nextDist = 0;
  177. }
  178.  
  179. void        MRConstruction::ScanConstruction(void)
  180. {
  181.     if(GetMarked())
  182.     {
  183.         if((oDistance<maxDist) && (oDistance>nextDist))
  184.             nextDist=oDistance;
  185.         if(HasNext())
  186.             ((MRConstruction *) NextRachet)->ScanConstruction();
  187.         if(nextDist==oDistance)
  188.         {
  189.             DoConstruction();
  190.             SetMarked(false);
  191.         }
  192.     }
  193.     else
  194.         if(HasNext())
  195.             ((MRConstruction *) NextRachet)->ScanConstruction();
  196.  
  197. }
  198.  
  199. Boolean        MRConstruction::ProposedMove(ChartPost    myMove)
  200. {  // is the proposed move going to keep me from bumping into walls ?
  201.     Boolean returnedPM=true; // assume the best
  202.     ChartPost    actor1={0,0};
  203.     ChartPost    actor2={0,0};
  204.     ChartPost    segment={0,0};
  205.     float    bMainLine;
  206.     ChartPost inter;
  207.     
  208.     if(HasNext())
  209.         returnedPM = ((MRConstruction *) NextRachet)->ProposedMove(myMove);
  210.     if(returnedPM==false)
  211.         return(returnedPM);
  212.     
  213.     switch(myBuildType)
  214.     {
  215.         case 1:
  216.         {
  217.             actor1=DiffChartPost(myMove,* (ChartPost *) myStructure);
  218.             if(sqrt(pow(actor1.myX,2)+pow(actor1.myY,2))>HumanStep)
  219.                 return(true);
  220.             else
  221.                 return(false);
  222.             break;    
  223.         }
  224.         case 2:
  225.         {  //  get tan of line, invert, use to get equation of pt through line.  calc intersection & distance.  if in question, solve for between pts
  226.             float slopeMainLine;
  227.             float slopeSecondLine;
  228.  
  229.             actor1=DiffChartPost(myMove,(* (ChartWall *) myStructure).CP1);
  230.             actor2=DiffChartPost(myMove,(* (ChartWall *) myStructure).CP2);
  231.             
  232.             segment=DiffChartPost(actor1,actor2);
  233.             if(segment.myX==0)
  234.                 segment.myX=.017;
  235.             slopeMainLine=segment.myY/segment.myX;
  236.             if(slopeMainLine==0)
  237.                 slopeMainLine=.017;
  238.             slopeSecondLine=(-1/slopeMainLine);
  239.             bMainLine =  actor2.myY-(slopeMainLine*actor2.myX);
  240.     
  241.             inter.myX=bMainLine/(slopeSecondLine-slopeMainLine);
  242.             inter.myY=slopeSecondLine*inter.myX;
  243.             
  244.             // get an ordered list of the points
  245.             ChartWall orderedList=LowHigh(actor1,actor2);
  246.             // fix the line to within the box
  247.             if(orderedList.CP1.myX>inter.myX)
  248.                 inter.myX=orderedList.CP1.myX;
  249.             if(orderedList.CP1.myY>inter.myY)
  250.                 inter.myY=orderedList.CP1.myY;
  251.             if(orderedList.CP2.myX<inter.myX)
  252.                 inter.myX=orderedList.CP2.myX;
  253.             if(orderedList.CP2.myY<inter.myY)
  254.                 inter.myY=orderedList.CP2.myY;
  255.             
  256.             
  257.             // if the line comes nowhere near us, return OK/true
  258.             if(sqrt(pow(inter.myX,2)+pow(inter.myY,2))>HumanStep)
  259.                 return(true);
  260.             else
  261.                 return(false);            
  262.             break;    
  263.         }
  264.         default:  // default for zero!
  265.             return(true);
  266.     }
  267.     
  268.         
  269. }
  270.  
  271. void        MRConstruction::DoConstruction(void)
  272. {
  273.  
  274.     if(GetNum()!=0)
  275.     {
  276.         switch(myBuildType)
  277.         {
  278.             case 1:
  279.             {
  280.                 DrawPost(* (ChartPost *) myActors);
  281.                 break;
  282.             }
  283.             case 2:
  284.             {
  285.                 DrawWall((* (ChartWall *) myActors).CP1,(* (ChartWall *) myActors).CP2,myWallType);
  286.                 break;
  287.             }
  288.         }
  289.     }
  290. }
  291.  
  292.  
  293.  
  294. void DrawPost(ChartPost CP)
  295. {
  296.     Point        refPoint={0,0};
  297.  
  298.     refPoint = FindFooter(CP);
  299.     MoveTo(refPoint.h+HorizonLine,refPoint.v+MeridianLine);
  300.     LineTo(refPoint.h+HorizonLine,MeridianLine-refPoint.v);
  301. }
  302.  
  303. void    DrawWall(ChartPost CP1,ChartPost CP2,char wallType)
  304. {
  305.  
  306.     Point        refPoint1={0,0};
  307.     Point        refPoint2={0,0};
  308.     PolyHandle    triPoly;
  309.     
  310.     refPoint1=FindFooter(CP1);
  311.     refPoint2=FindFooter(CP2);
  312.  
  313.     triPoly = OpenPoly();
  314.         MoveTo(refPoint1.h+HorizonLine,refPoint1.v+MeridianLine);
  315.         LineTo(refPoint1.h+HorizonLine,MeridianLine-refPoint1.v);
  316.         LineTo(refPoint2.h+HorizonLine,MeridianLine-refPoint2.v);
  317.         LineTo(refPoint2.h+HorizonLine,refPoint2.v+MeridianLine);
  318.         LineTo(refPoint1.h+HorizonLine,refPoint1.v+MeridianLine);
  319.     ClosePoly();
  320.     
  321.     switch((short) Min(CP1.myY,CP2.myY))
  322.     {
  323.     case    0:
  324.     case    1:
  325.         FillCPoly (triPoly, WallPenPattern[wallType][0]);break;
  326.     case    2:
  327.     case    3:
  328.         FillCPoly (triPoly, WallPenPattern[wallType][1]);break;
  329.     case    4:
  330.     case    5:
  331.         FillCPoly (triPoly, WallPenPattern[wallType][2]);break;
  332.     default    :
  333.         FillPoly(triPoly,black);break;
  334.     }
  335.     
  336.     FramePoly(triPoly);
  337. //    if(QDError != noErr)
  338. //        DoError("\pCan't draw Polygon.  No memory?");
  339.     KillPoly(triPoly);
  340. }
  341.  
  342. Point    FindFooter(ChartPost CP)
  343. {  //  use to place a footer (x,y) onto the screen with "realism"
  344.     Point        refPoint={0,0};
  345.  
  346.     if(CP.myY<0)
  347.         refPoint.v=MeridianLine-atan2(-(CP.myY),UnitHeight)*MerdSpan;
  348.     else
  349.         refPoint.v=MeridianLine-atan2(CP.myY,UnitHeight)*MerdSpan;
  350.     refPoint.h= refPoint.v*CP.myX*ViewRatio;
  351.     return(refPoint);
  352. }
  353.  
  354.  
  355. ChartPost    FindActor(ChartPost target,float rads, Boolean halfCircle)
  356. {  // target must be in relative terms.  info passed back in actorY,actorY
  357.  
  358.     //  get the slope of the line that runs perpendicular to the way we are looking
  359.     float slopeMainLine=tan(rads);
  360.     if(slopeMainLine==0)
  361.         slopeMainLine=.017;  // we don't want exactly zero
  362.     float slopeSecondLine=(-1/slopeMainLine);
  363.         
  364.     //  get the B of the second line (y=slope*x+b, where b is 0 in first equation)
  365.     float    bSecondLine = target.myY-(slopeSecondLine*target.myX);
  366.     
  367.     // calculate the intersection of the line and a perpendicular line through the point
  368.     ChartPost inter={bSecondLine/(slopeMainLine-slopeSecondLine),slopeMainLine*inter.myX};
  369.  
  370.     //     find the actor!
  371.     ChartPost actor={sqrt(inter.myX*inter.myX+inter.myY*inter.myY),sqrt(pow(target.myX-inter.myX,2)+pow(inter.myY-target.myY,2))};
  372.     
  373.     // fix the sign if angled to the left
  374.     if(inter.myX<0)
  375.         actor.myX= -actor.myX;
  376.     // fix the direction of angled backwards
  377.     if(!halfCircle)
  378.         actor.myX = -actor.myX;
  379.         
  380.     //  if it's behind us,flip the sign
  381.     if(!(halfCircle==false && (target.myX*slopeMainLine)<target.myY) && !(halfCircle==true && (target.myX*slopeMainLine)>target.myY))
  382.         actor.myY = -actor.myY;
  383.     return(actor);
  384. }
  385.  
  386. void NormalizeAngle(float &facing, Boolean &halfCircle)
  387. {
  388.  
  389.     if(facing<-MyHalfPi)
  390.     {
  391.         facing+=MyPi;
  392.         halfCircle= !halfCircle;
  393.     }
  394.     if(facing>MyHalfPi)
  395.     {
  396.         facing-=MyPi;
  397.         halfCircle = !halfCircle;
  398.     }
  399.     
  400. }
  401.  
  402.  
  403. ChartPost    ReturnChartPost(float myX,float myY)
  404. {
  405.     ChartPost    CP={myX,myY};
  406.     return (CP);
  407. }
  408.  
  409. ChartWall    ReturnChartWall(ChartPost CP1,ChartPost    CP2)
  410. {
  411.     ChartWall    CW={CP1.myX,CP1.myY,CP2.myX,CP2.myY};
  412.     return(CW);
  413. }
  414.  
  415. ChartWall    LowHigh(ChartPost lowCP,ChartPost highCP)
  416. { // reorders coordinates of box to low->high and adds margin of error
  417.     
  418.     ChartWall CW={Min(lowCP.myX,highCP.myX)-.1,Min(lowCP.myY,highCP.myY)-.1,Max(lowCP.myX,highCP.myX)+.1,Max(lowCP.myY,highCP.myY)+.1};
  419.     return(CW);
  420.     
  421. //    float slopeMainLine = (CP2.myY-CP1.myY)/( (CP2.myX-CP1.myX)==0 ? .017 : (CP2.myX-CP1.myX) ) ;
  422. //    if(slopeMainLine==0)
  423. //        slopeMainLine=.017;
  424. //    float tanMainLine = atan(slopeMainLine);
  425. //    CP1.myX-=cos(tanMainLine);
  426. //    CP1.myY-=sin(tanMainLine);
  427. //    CP2.myX+=cos(tanMainLine);
  428. //    CP2.myY+=sin(tanMainLine);
  429. //    lowCP=CP1;
  430. //    highCP=CP2;
  431. }
  432.  
  433.  
  434.  
  435.  
  436.